package com.book.remote;

import com.book.activeMQ.productor.ProductMQ;
import com.book.common.OrderPayTypeEnum;
import com.book.common.OrderStatusEnum;
import com.book.dto.*;
import com.book.helper.AddressHelper;
import com.book.helper.OrderVoHelper;
import com.book.pojo.*;
import com.book.redis.RedisRandomProvider;
import com.book.service.*;
import com.book.util.DateUtil;
import com.book.vo.*;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author 李锦程
 * @Date 2021/4/27 1:26 下午
 * @Package com.book.service.impl
 * @Version 1.0
 */
@Slf4j
@Service
public class OrderRemote {
    private static String YSW = "YSW";
    @Autowired
    private OrderService orderService;
    @Autowired
    private BookService uBookService;
    @Autowired
    private RedisRandomProvider provider;
    @Autowired
    private ShopCarDetailService shopCarDetailService;
    @Autowired
    private ImgService imageService;
    @Autowired
    private AddressService addressService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private ProductMQ productMQ;
    @Autowired
    private UserService userService;

    public Integer save(OrderDto orderDto, String carIds) {
        orderDto.setOrderCode(getOrderCode());
        orderDto.setOrderStatus((short) 0);
        orderDto.setOrderCreate(new Date());
        String[] carIdArr = carIds.split(",");
        List<OrderDetailDto> list = Lists.newArrayList();
        for (String s : carIdArr) {
            OrderDetailDto detailDto = new OrderDetailDto();
            ShopDetail shopCarBook = shopCarDetailService.getShopCarBook(Integer.parseInt(s));
            detailDto.setUbCode(shopCarBook.getUbCode());
            detailDto.setOrNum(shopCarBook.getSdNum());
            detailDto.setOrPrice(shopCarBook.getPrice());
            detailDto.setOrderCode(orderDto.getOrderCode());
            list.add(detailDto);
        }
        log.info("######发送消息");
        return 1;
    }

    public List<OrderVo> getListByUId(String userCode) {
        List<OrderDto> orderListByUser = orderService.getOrderListByUser(userCode);
        if (CollectionUtils.isEmpty(orderListByUser)) {
            return Lists.newArrayList();
        }
        return getOrderVoList(orderListByUser);
    }

    private List<OrderVo> getOrderVoList(List<OrderDto> source) {
        List<OrderVo> list = Lists.newArrayList();
        source.forEach(m -> {
            OrderVo orderVo = new OrderVo();
            orderVo.setOrderNo(m.getOrderCode());
            orderVo.setCreateTime(sdfDate(m.getOrderCreate()));
            orderVo.setId(m.getId());
            orderVo.setPrice(m.getOrderPrice());
            orderVo.setStatusValue(OrderStatusEnum.getMsg((int) m.getOrderStatus()));
            orderVo.setStatus(Integer.valueOf(m.getOrderStatus()));
            list.add(orderVo);
        });
        return list;
    }

    private String sdfDate(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(date);
    }

    public OrderDetailVo getOrderById(Integer id) {
        OrderDto orderById = orderService.getOrderById(id);
        if (orderById == null) {
            return null;
        }
        OrderDetailVo detailVo = new OrderDetailVo();
        detailVo.setOrderNo(orderById.getOrderCode());
        detailVo.setOrderNote(orderById.getOrderNote());
        detailVo.setPrice(orderById.getOrderPrice());
        detailVo.setStatus(OrderStatusEnum.getMsg((int) orderById.getOrderStatus()));
        detailVo.setPayType(OrderPayTypeEnum.getMsg(orderById.getPayType()));
        getOrderBook(detailVo);
        setOrderDetailAddress(detailVo, orderById.getAddressId());
        return detailVo;
    }

    private void getOrderBook(OrderDetailVo detailVo) {
        String orderNo = detailVo.getOrderNo();
        List<OrderDetailDto> orderDetailByOrderNo = orderService.getOrderDetailByOrderNo(orderNo);
        if (CollectionUtils.isEmpty(orderDetailByOrderNo)) {
            return;
        }
        List<OrderBookVo> list = Lists.newArrayList();
        orderDetailByOrderNo.forEach(m -> {
            OrderBookVo orderBookVo = new OrderBookVo();
            orderBookVo.setBookCode(m.getUbCode());
            orderBookVo.setNum((int) m.getOrNum());
            orderBookVo.setPrice(m.getOrPrice());
            BookDto uBookByCode = uBookService.getUBookByCode(m.getUbCode());
            orderBookVo.setBookName(uBookByCode.getBookTitle());
            List<String> imgUrls = imageService.getImgByBookCode(m.getUbCode());
            orderBookVo.setImgUrl(imgUrls.get(0));
            orderBookVo.setBookAuthor(uBookByCode.getBookAuthor());
            Category categoryById2 = categoryService.getCategoryById(uBookByCode.getClassId());
            Category categoryById1 = categoryService.getCategoryById(categoryById2.getPid());
            orderBookVo.setCategory(categoryById1.getCname() + " > " + categoryById2.getCname());
            list.add(orderBookVo);
        });
        detailVo.setOrderBookVoList(list);
    }

    private void setOrderDetailAddress(OrderDetailVo vo, Integer addressId) {
        Address addressById = addressService.getAddressById(addressId);
        if (addressById != null) {
            vo.setAddressDto(AddressHelper.covertPoDto(addressById));
        }
    }

    public Boolean saveOrder(OrderDto orderDto, String bookCode) {
        try {
            orderDto.setOrderStatus((short) 0);
            orderDto.setOrderCreate(new Date());
            log.info("saveOrder#orderDto:{}", orderDto);
            Integer integer = orderService.insertOrder(orderDto);
            if (integer == 1){
                productMQ.saveOrderDetail(orderDto.getOrderCode());
            }else {
                productMQ.resetOrderDetail(orderDto.getOrderCode());
            }
            return integer == 1;
        } catch (Exception e) {
            log.error("OrderRemote.saveOrder#异常", e);
            return false;
        }
    }

    public String getOrderCode() {
        return YSW + DateUtil.getDateUtil() + provider.getNo();
    }

    public Map<String, List<OrderBookVo>> getShopDetailList(List<Integer> ids) {
        List<ShopDetailDto> shopCarDetail = shopCarDetailService.getShopCarDetail(ids);
        if (CollectionUtils.isEmpty(shopCarDetail)) {
            return Maps.newHashMap();
        }
        List<String> bookCodeList = shopCarDetail.stream().map(ShopDetailDto::getUbCode).collect(Collectors.toList());
        log.info("OrderRemote.getShopDetailList bookCodeList:{}", bookCodeList);
        List<BookDto> bookListByBookCode = uBookService.getBookListByBookCode(bookCodeList);
        if (CollectionUtils.isEmpty(bookCodeList)) {
            return Maps.newHashMap();
        }
        log.info("OrderRemote.getShopDetailList bookListByBookCode:{}", bookCodeList);
        List<Integer> uIdList = bookListByBookCode.stream().map(BookDto::getUId).collect(Collectors.toList());
        List<UserDto> userNameList = userService.getUserName(uIdList);
        Map<Integer, String> userMap = userNameList.stream().collect(Collectors.toMap(UserDto::getId, UserDto::getUName));
        Map<String, List<BookDto>> bookDtoMap = bookListByBookCode.stream().collect(Collectors.groupingBy(BookDto::getBookCode));
        Map<String, List<OrderBookVo>> resultMap = Maps.newHashMap();
        List<Category> categoryList = categoryService.getCategoryList(0);
        Map<Integer, String> cateNameMap = Maps.newHashMap();
        categoryList.forEach(m -> {
            String firstCateName = m.getCname();
            List<Category> categoryList1 = categoryService.getCategoryList(m.getId());
            categoryList1.forEach(n -> {
                cateNameMap.put(n.getId(), firstCateName + " > " + n.getCname());
            });
        });
        List<OrderBookVo> bookVos = Lists.newArrayList();
        shopCarDetail.forEach(m -> {
            OrderBookVo orderBookVo = new OrderBookVo();
            BookDto bookDto = bookDtoMap.get(m.getUbCode()).get(0);
            if (m.getSdNum() <= bookDto.getBookNum()) {
                orderBookVo.setNum(Integer.valueOf(m.getSdNum()));
                orderBookVo.setTotalPrice(m.getPrice());
                orderBookVo.setIsAmple("充足");
            } else {
                orderBookVo.setNum(bookDto.getBookNum());
                orderBookVo.setTotalPrice(bookDto.getBookNum() * bookDto.getBookPrice());
                orderBookVo.setIsAmple("不足，已自动调整最大值");
            }
            orderBookVo.setPrice(bookDto.getBookPrice());
            orderBookVo.setBookName(bookDto.getBookTitle());
            orderBookVo.setBookAuthor(bookDto.getBookAuthor());
            orderBookVo.setBookCode(bookDto.getBookCode());
            orderBookVo.setCategory(cateNameMap.get(bookDto.getClassId()));
            List<String> imgByBookCode = imageService.getImgByBookCode(bookDto.getBookCode());
            if (CollectionUtils.isNotEmpty(imgByBookCode)) {
                orderBookVo.setImgUrl(imgByBookCode.get(0));
            }
            orderBookVo.setUId(bookDto.getUId());
            bookVos.add(orderBookVo);
        });
        if (CollectionUtils.isEmpty(bookVos)) {
            return null;
        }
        Map<Integer, List<OrderBookVo>> bookVoMap = bookVos.stream().collect(Collectors.groupingBy(OrderBookVo::getUId));
        for (Integer id : bookVoMap.keySet()
        ) {
            String s = userMap.get(id);
            resultMap.put(s, bookVoMap.get(id));
        }
        return resultMap;
    }

    public String setOrderDetailCache(Map<String, List<OrderBookVo>> vos) {
        List<List<OrderBookVo>> voList = Lists.newArrayList(vos.values());
        if (CollectionUtils.isEmpty(voList)) {
            return null;
        }
        List<OrderBookVo> bookVos = Lists.newArrayList();
        voList.forEach(bookVos::addAll);
        List<TempOrderBookDto> collect = bookVos.stream().map(OrderVoHelper::covertVoToTempDto).collect(Collectors.toList());
        String orderNo = getOrderCode();
        Map<String, List<TempOrderBookDto>> map = Maps.newHashMap();
        map.put(orderNo, collect);
        productMQ.saveTempOrder(map);
        return orderNo;
    }

    public Map<String, List<OrderBookVo>> getOrderToPlace(String bookCode, Integer num) {
        BookDto uBookByCode = uBookService.getUBookByCode(bookCode);
        OrderBookVo orderBookVo = new OrderBookVo();
        orderBookVo.setBookCode(bookCode);
        orderBookVo.setBookName(uBookByCode.getBookTitle());
        orderBookVo.setPrice(uBookByCode.getBookPrice());
        orderBookVo.setBookAuthor(uBookByCode.getBookAuthor());
        orderBookVo.setUId(uBookByCode.getUId());
        if (num <= uBookByCode.getBookNum()) {
            orderBookVo.setNum(num);
            orderBookVo.setIsAmple("充足");
            orderBookVo.setTotalPrice(uBookByCode.getBookPrice() * num);
        } else if (uBookByCode.getBookNum() == 0) {
            orderBookVo.setNum(0);
            orderBookVo.setTotalPrice(0.0);
            orderBookVo.setIsAmple("没有货啦");
        } else {
            orderBookVo.setNum(uBookByCode.getBookNum());
            orderBookVo.setTotalPrice(uBookByCode.getBookNum() * uBookByCode.getBookPrice());
            orderBookVo.setIsAmple("数量不足，已自动调整最大");
        }
        List<String> imgByBookCode = imageService.getImgByBookCode(bookCode);
        if (CollectionUtils.isNotEmpty(imgByBookCode)) {
            orderBookVo.setImgUrl(imgByBookCode.get(0));
        }
        Category categoryById = categoryService.getCategoryById(uBookByCode.getClassId());
        Category categoryById1 = categoryService.getCategoryById(categoryById.getPid());
        String cate = categoryById1.getCname() + " > " + categoryById.getCname();
        orderBookVo.setCategory(cate);
        String uName = userService.getUserById(uBookByCode.getUId()).getUName();
        Map<String,List<OrderBookVo>> map = Maps.newHashMap();
        map.put(uName,Lists.newArrayList(orderBookVo));
        return map;
    }

    public List<MySellerVo> getMySellInfo(Integer uId){
        List<BookDto> bookListByUId = uBookService.getBookListByUId(uId);
        List<String> bookNoList = bookListByUId.stream().map(BookDto::getBookCode).collect(Collectors.toList());
        Map<String,BookDto> bookMap = bookListByUId.stream().collect(Collectors.toMap(BookDto::getBookCode, Function.identity(),(k1,k2)->k1));
        List<OrderDetailDto> orderDetailDtos =orderService.getOrderDetailByBookCodeList(bookNoList);
        List<MySellerVo> mySellerVoList = Lists.newArrayList();
        Map<String,List<OrderDetailDto>> orderMap = orderDetailDtos.stream().collect(Collectors.groupingBy(OrderDetailDto::getOrderCode));
        for (String orderNo : orderMap.keySet()){
            OrderBook order = orderService.getOrderByNo(orderNo);
            if (order == null){
                continue;
            }
            MySellerVo mySellerVo = new MySellerVo();
            mySellerVo.setOrderNo(orderNo);
            mySellerVo.setOrderNote(order.getOrderNote());
            mySellerVo.setOrderTime(sdfDate(order.getOrderCreate()));
            mySellerVo.setTotalPrice(order.getOrderPrice());
            mySellerVo.setOrderStatus(OrderStatusEnum.getMsg(Integer.valueOf(order.getOrderStatus())));
            User userByCode = userService.getUserByCode(order.getUCode());
            mySellerVo.setBuyUserName(userByCode.getUName());
            List<OrderDetailDto> orderDetailDtoList = orderMap.get(orderNo);
            List<MySellVo2> vo2List = Lists.newArrayList();
            orderDetailDtoList.forEach(m->{
                MySellVo2 mySellVo2 = new MySellVo2();
                BookDto bookDto = bookMap.get(m.getUbCode());
                mySellVo2.setBookCode(bookDto.getBookCode());
                mySellVo2.setBookTitle(bookDto.getBookTitle());
                mySellVo2.setPrice(bookDto.getBookPrice());
                mySellVo2.setNum(Integer.valueOf(m.getOrNum()));
                mySellVo2.setSubTotal(mySellVo2.getPrice()*mySellVo2.getNum());
                List<String> imgByBookCode = imageService.getImgByBookCode(bookDto.getBookCode());
                if (CollectionUtils.isNotEmpty(imgByBookCode)){
                    mySellVo2.setImg(imgByBookCode.get(0));
                }
                vo2List.add(mySellVo2);
            });
            mySellerVo.setMySellVo2List(vo2List);
            mySellerVoList.add(mySellerVo);
        }
        return mySellerVoList;
    }

    public Boolean updateOrderStatus(Integer id, int i) {
        OrderBook orderBook = new OrderBook();
        orderBook.setId(id);
        orderBook.setOrderStatus((short) i);
        Integer integer = orderService.updateOrder(orderBook);
        if(integer == 1 && i == 2){
            OrderDto orderById = orderService.getOrderById(id);
            productMQ.resetOrderDetail(orderById.getOrderCode());
        }
        return integer == 1;
    }

    public List<OrderVo> searchByNameOrStatus(String uCode,String text, Integer status) {
        List<OrderDto> orderBySearch = orderService.getOrderBySearch(uCode, text, status);
        if (CollectionUtils.isEmpty(orderBySearch)) {
            return Lists.newArrayList();
        }
        return getOrderVoList(orderBySearch);
    }
}
